%{
	void countrc(void);
%}

%option noyywrap

hex_digit        [0-9A-F]
digit            [0-9]
alpha            [a-zA-Z_]
white_space      [ \r\t\n]*
num              ("-")?{digit}+
uint             {digit}+
int              "-"{digit}+
float            ({num})("."{num}?)
hex_uint         {hex_digit}+"h"
hex_int          "-"{hex_digit}+"h"
identifier       {alpha}+({digit}|{alpha})*

%%

"("             { countrc(); FLEX_PRINT("("); return '('; }
")"             { countrc(); FLEX_PRINT(")"); return ')'; }
"+="            { countrc(); FLEX_PRINT("+="); return ADD_ASSIGN; }
"-="            { countrc(); FLEX_PRINT("-="); return SUB_ASSIGN; }
"*="            { countrc(); FLEX_PRINT("*="); return MUL_ASSIGN; }
"/="            { countrc(); FLEX_PRINT("/="); return DIV_ASSIGN; }
"++"            { countrc(); FLEX_PRINT(";"); return INCREMENT; }
"--"            { countrc(); FLEX_PRINT(";"); return DECREMENT; }
";"             { countrc(); FLEX_PRINT(";"); return ';'; }
"="             { countrc(); FLEX_PRINT("="); return '='; }
"+"             { countrc(); FLEX_PRINT("+"); return '+'; }
"-"             { countrc(); FLEX_PRINT("-"); return '-'; }
"*"             { countrc(); FLEX_PRINT("*"); return '*'; }
"/"             { countrc(); FLEX_PRINT("/"); return '/'; }

"goto"          { countrc(); FLEX_PRINT("goto"); return GOTO; }

{hex_uint}      { countrc(); sscanf(yytext, "%X", &yylval.u); FLEX_PRINT("UINT_CONST (%u)", yylval.u); return UINT_CONST; }
{hex_int}       { countrc(); sscanf(yytext, "%X", &yylval.s); FLEX_PRINT("INT_CONST (%d)", yylval.s); return INT_CONST; }

{uint}          { countrc(); sscanf(yytext, "%u", &yylval.u); FLEX_PRINT("UINT_CONST (%u)", yylval.u); return UINT_CONST; }
{int}           { countrc(); sscanf(yytext, "%d", &yylval.s); FLEX_PRINT("INT_CONST (%d)", yylval.s); return INT_CONST; }
{float}         { countrc(); sscanf(yytext, "%f", &yylval.f); FLEX_PRINT("FLOAT_CONST (%f)", yylval.f); return FLOAT_CONST; }
{identifier}    { countrc(); memcpy(identifierBuff, yytext, (identifierLen = yyleng + 1)); FLEX_PRINT("IDENTIFIER (%s)", yytext); return IDENTIFIER; }

"//"[^\n]*      { countrc(); /* do nothing */ }
{white_space}   { countrc(); FLEX_PRINT("ws"); /* do nothing */ }
.               { countrc(); yyerror("Illegal input\n"); system("pause"); return 0; }
<<EOF>>         { countrc(); FLEX_PRINT("EOF"); return 0; }

%%

void countrc(void)
{
	const char* p;

	for (p = yytext; *p != '\0'; ++p)
	{
		if (*p == '\n')
			col = 0, ++row;
		else
			++col;
	}
}

void yyerror(const char* s)
{
	COMPILER_ERRORF("Error on line %u - %s\n", row, s);
}
